#include "ResultHandler.h"
#include <sqlite3.h>

int callback(void *NotUsed, int argc, char **argv, char **azColName)
{
        for(int i = 0 ; i < argc ; i++)
        {
                std::cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL") << ", " ;
        }
        std::cout<< "\n";
        return 0;
}

//ResultHandler::ResultHandler(){}
ResultHandler::~ResultHandler(){}
ResultHandler::ResultHandler(QueryPacket &queryP,std::vector<NTuple> &resS){
	std::cout << "Initial ResultHandler begin..." << std::endl;
	queryPacket = queryP;
	resultS = resS;
	std::cout << "Initial ResultHandler done!..." << std::endl;
}
std::vector<NTuple> ResultHandler::join(){
	std::vector<std::string> tpVars;   //正在查询的子查询语句的变量
	std::vector<std::string> nextVariables; // 后续需要查询的语句的变量
	std::vector<std::string> ansVariables; //需要回答的变量，最终的变量目标
	std::vector<std::string> partialVariables; //已经有的答案的变量目标
	int debug=1;

	for(int i=0;i<queryPacket.variable_size;i++)
		ansVariables.push_back(queryPacket.variables[i]);

	for(int j=0;j<3;j++){
		if(queryPacket.subquery_patterns.at(queryPacket.current_subquery).pattern[j]==14){   // pattern is subquery variable
			tpVars.push_back(queryPacket.subquery_variables.at(queryPacket.current_subquery).at(j));
		}
	}

	for(int i=queryPacket.current_subquery+1;i<queryPacket.subquery_size;i++){
		for(int j=0;j<3;j++){
			if(queryPacket.subquery_patterns.at(i).pattern[j]==14){   // pattern is subquery variable
				nextVariables.push_back(queryPacket.subquery_variables.at(i).at(j));
			}
		}
	}
	for(int i=0; i<1;i++){
		for(int j=0; j<queryPacket.partial_ans.at(i).variables.size();j++){
			partialVariables.push_back(queryPacket.partial_ans.at(i).bindings.at(j).variableName);
		}
	}

	if(debug){
		std::vector<std::string>::iterator tpVars_beg=tpVars.begin();
		std::vector<std::string>::iterator tpVars_end=tpVars.end();
		for(std::vector<std::string>::iterator it=tpVars_beg;it!=tpVars_end;it++){
			std::cout << "tpVars: " << *it << std::endl;
		}
		std::vector<std::string>::iterator nextVariables_beg=nextVariables.begin();
		std::vector<std::string>::iterator nextVariables_end=nextVariables.end();
		for(std::vector<std::string>::iterator it=nextVariables_beg;it!=nextVariables_end;it++){
			std::cout << "nextVariables: " << *it << std::endl;
		}
		std::vector<std::string>::iterator partialVariables_beg=partialVariables.begin();
		std::vector<std::string>::iterator partialVariables_end=partialVariables.end();
		for(std::vector<std::string>::iterator it=partialVariables_beg;it!=partialVariables_end;it++){
			std::cout << "partialVariables: " << *it << std::endl;
		}
	}


	if(queryPacket.ans_size!=0){
		//FIX ME
		//add sth


	}else{ // THE first tp
		//FIX ME
	}



	int rc=sqlite3_open(":memory:",&pDB);


//	int rc=sqlite3_open("result.db",&pDB);
    if( rc ){
        std::cout << "Can't open database: "<< sqlite3_errmsg(pDB);
//        sqlite3_close(pDB);
        return partialResult;
    }else{
    	std::cout << "Open result.db successsfully!" << std::endl;
    }

	//获取子查询语句的变量
//	std::vector<std::vector<std::string> >::iterator clause_var_beg=queryPacket.subquery_variables.begin();
//	std::vector<std::vector<std::string> >::iterator clause_var_end=queryPacket.subquery_variables.end();

//	for(int i=0;i<queryPacket.subquery_size;i++){
//		for(int j=0;j<3;j++){
//			if(queryPacket.subquery_patterns.at(i).pattern[j]==14){   // pattern is subquery variable
//				tpVars.push_back(queryPacket.subquery_variables.at(i).at(j));
//			}
//		}
//	}
//	std::vector<std::string>::iterator tpVars_beg=tpVars.begin();
//	std::vector<std::string>::iterator tpVars_end=tpVars.end();
//	for(std::vector<std::string>::iterator it=tpVars_beg;it!=tpVars_end;it++){
//		std::cout << *it << " " ;
//	}

	std::string tempTable;
	if(queryPacket.ans_size!=0){
		std::cout << "queryPacket answer is not NULL!" << std::endl;
		std::cout << queryPacket.current_subquery << std::endl;
		std::cout << "Storing " << queryPacket.ans_size << " triples to a temporary relation." << std::endl;
		int columns = queryPacket.partial_ans.at(0).bindings.size();
		std::cout << "The columns of partial_ans 1 is " << columns << std::endl;
		tempTable="temp_"+iToString(queryPacket.query_id)+"_"+iToString(queryPacket.current_subquery-1);
	}
	std::string createTableStatement;
	createTableStatement.append("CREATE TABLE ");
	createTableStatement.append(tempTable);
	createTableStatement.append(" (");

	std::vector<std::string>::iterator partialVariables_it=partialVariables.begin();
	for(int i=0;i<partialVariables.size();i++,partialVariables_it++){
		if(i!=partialVariables.size()-1){
			createTableStatement.append("tempvar");
			createTableStatement.append(*partialVariables_it);
			createTableStatement.append(" TEXT, ");
		}
		else{
			createTableStatement.append("tempvar");
			createTableStatement.append(*partialVariables_it);
			createTableStatement.append(" TEXT");
		}
	}
	createTableStatement.append(" )");
	createTableStatement.append(";");
	std::cout << createTableStatement << std::endl;
	char* errMsg;
    rc = sqlite3_exec(pDB , createTableStatement.c_str() ,0 ,0, &errMsg);

      if (rc != SQLITE_OK)
      {
              std::cout << "执行创建table的SQL 出错." << errMsg << std::endl;
              return partialResult;
      }
      else
      {
              std::cout << "创建table的SQL成功执行."<< std::endl;
      }


      std::cout << "QueryPacket.ans_size= " << queryPacket.ans_size << std::endl;
      for(int i=0; i<queryPacket.ans_size; i++){
          std::string insertStatement;
          insertStatement.append("insert into " + tempTable + " values (");
          for(int j=0;j< partialVariables.size();j++){
        		if(j!=partialVariables.size()-1){
        			insertStatement.append("'"+queryPacket.partial_ans.at(i).bindings.at(j).value+"'"+",");
        		}
        		else{
        			insertStatement.append("'"+queryPacket.partial_ans.at(i).bindings.at(j).value+"'");
        		}
          }
  		  insertStatement.append(" )");
  		  insertStatement.append(";");
          std::cout << insertStatement << std::endl;

          rc = sqlite3_exec(pDB , insertStatement.c_str() ,0 ,0, &errMsg);

            if (rc != SQLITE_OK)
            {
                    std::cout << "执行insert的SQL 出错." << errMsg << std::endl;
                    return partialResult;
            }
            else
            {
                    std::cout << "创建insert的SQL成功执行."<< std::endl;
            }
      }

      std::string tempTable2;
      //存储这次搜索语句的数据库
      if(resultS.size()!=0){

    	  tempTable2="temp_"+iToString(queryPacket.query_id)+"_"+iToString(queryPacket.current_subquery);
    	  std::cout << "The columns of current query is " << tpVars.size() << std::endl;
    		std::string createTableStatement2;
    		createTableStatement2.append("CREATE TABLE ");
    		createTableStatement2.append(tempTable2);
    		createTableStatement2.append(" (");

    		std::vector<std::string>::iterator tpVars_it=tpVars.begin();
    		for(int i=0;i<tpVars.size();i++,tpVars_it++){
    			if(i!=tpVars.size()-1){
    				createTableStatement2.append("tempvar2");
    				createTableStatement2.append(*tpVars_it);
    				createTableStatement2.append(" TEXT, ");
    			}
    			else{
    				createTableStatement2.append("tempvar2");
    				createTableStatement2.append(*tpVars_it);
    				createTableStatement2.append(" TEXT");
    			}
    		}
    		createTableStatement2.append(" )");
    		createTableStatement2.append(";");
    		std::cout << createTableStatement2<< std::endl;
    	    rc = sqlite3_exec(pDB , createTableStatement2.c_str() ,0 ,0, &errMsg);

    	      if (rc != SQLITE_OK)
    	      {
    	              std::cout << "执行创建table的SQL 出错." << errMsg << std::endl;
    	              return partialResult;
    	      }
    	      else
    	      {
    	              std::cout << "创建table的SQL成功执行."<< std::endl;
    	      }

    	      for(int i=0; i<resultS.size(); i++){
    	          std::string insertStatement2;
    	          insertStatement2.append("insert into " + tempTable2 + " values (");
    	          for(int j=0;j< tpVars.size();j++){
    	        		if(j!=tpVars.size()-1){
    	        			insertStatement2.append("'"+resultS.at(i).bindings.at(j).value+"'"+",");
    	        		}
    	        		else{
    	        			insertStatement2.append("'"+resultS.at(i).bindings.at(j).value+"'");
    	        		}
    	          }
	        	  insertStatement2.append(" )");
	        	  insertStatement2.append(";");
    	          std::cout << insertStatement2 << std::endl;

    	          rc = sqlite3_exec(pDB , insertStatement2.c_str() ,0 ,0, &errMsg);

    	            if (rc != SQLITE_OK)
    	            {
    	                    std::cout << "执行insert的SQL 出错." << errMsg << std::endl;
    	                    return partialResult;
    	            }
    	            else
    	            {
    	                    std::cout << "创建insert的SQL成功执行."<< std::endl;
    	            }
    	      }
      }

      // 找到共同的变量
    std::vector<std::string> joinVars;
    std::vector<std::string>::iterator partialVar_it=partialVariables.begin();
    for(int i=0;i<partialVariables.size();i++,partialVar_it++){
    	std::vector<std::string>::iterator result = find(tpVars.begin( ),tpVars.end(),*partialVar_it);
    	if(result!=tpVars.end()){
    		std::cout << "joined var= " << *partialVar_it << std::endl;
    		joinVars.push_back(*partialVar_it);
    	}
    }

    //需要设置主键，如果没有主键，将没办法进行后续工作
    int indexcount=0;
//    if(joinVars.size()>0){
//    	indexcount++;
//    	std::string createIndex;
//    	createIndex.append("CREATE INDEX IF NOT EXISTS ");
//    	createIndex.append(tempTable);
//    	createIndex.append(iToString(indexcount));
//    	createIndex.append(" ON ");
//    	createIndex.append(tempTable);
//    	createIndex.append("(");
//
//    	for(int i=0;i<joinVars.size();i++){
//    		if(i!=(joinVars.size()-1)){
//    			createIndex.append("tempvar");
//    			createIndex.append(joinVars.at(i));
//    			createIndex.append(",");
//    		}else{
//    			createIndex.append("tempvar");
//    			createIndex.append(joinVars.at(i));
//    		}
//    	}
//    	createIndex.append(");");
//        rc = sqlite3_exec(pDB , createIndex.c_str() ,0 ,0, &errMsg);
//
//          if (rc != SQLITE_OK)
//          {
//                  std::cout << "执行createIndex的SQL 出错." << errMsg << std::endl;
//                  return partialResult;
//          }
//          else
//          {
//                  std::cout << "创建createIndex的SQL成功执行."<< std::endl;
//          }
//
//    }

      //将两次查询的结果join在一起
    std::vector<std::string> vars;
    std::string selectStatement;
    selectStatement.append("SELECT DISTINCT");
    std::vector<std::string>::iterator tpVars_it2=tpVars.begin();
    for(int i=0;i<tpVars.size();i++,tpVars_it2++){
    	std::vector<std::string>::iterator result1 = find(ansVariables.begin( ),ansVariables.end(),*tpVars_it2);
    	std::vector<std::string>::iterator result2 = find(nextVariables.begin( ),nextVariables.end(),*tpVars_it2);
    	if(result1!=ansVariables.end()||result2!=nextVariables.end()){
    		vars.push_back(*tpVars_it2);
    		selectStatement.append(" tempvar2"+*tpVars_it2+",");
    	}
    }


    if(queryPacket.ans_size!=0){
    	  std::vector<std::string>::iterator partialVariables_it=partialVariables.begin();
    	  for(int i=0;i<partialVariables.size();i++,partialVariables_it++){
    		  std::vector<std::string>::iterator result1 = find(ansVariables.begin( ),ansVariables.end(),*partialVariables_it);
    		  std::vector<std::string>::iterator result2 = find(nextVariables.begin( ),nextVariables.end(),*partialVariables_it);
    		  std::vector<std::string>::iterator result3 = find(tpVars.begin( ),tpVars.end(),*partialVariables_it);
    		  if((result1!=ansVariables.end()||result2!=nextVariables.end())
    				  && result3==tpVars.end()){
    			  selectStatement.append(" tempvar"+*partialVariables_it+",");
    			  vars.push_back(*partialVariables_it);
    		  }
    	  }
    }
   selectStatement.replace(selectStatement.size()-1,1," "); //将最后的逗号改为空格
   selectStatement.append(" FROM " + tempTable + " , " + tempTable2);

   //此处应该加入某些条件，如果没有共同变量的情况
   if(joinVars.size()>0){
	   selectStatement.append(" WHERE ");
	   for(int i=0;i<joinVars.size();i++){
		   if(i!=joinVars.size()-1){
			   selectStatement.append(tempTable+".tempvar"+joinVars.at(i));
			   selectStatement.append("=");
			   selectStatement.append(tempTable2+".tempvar2"+joinVars.at(i));
			   selectStatement.append(" AND ");
		   }else{
			   selectStatement.append(tempTable+".tempvar"+joinVars.at(i));
			   selectStatement.append("=");
			   selectStatement.append(tempTable2+".tempvar2"+joinVars.at(i));
		   }
	   }
   }
   selectStatement.append(";");
   std::cout << selectStatement << std::endl;

//   std::string selectStatement2="SELECT *  FROM temp_1_0,temp_1_1";
//   rc = sqlite3_exec(pDB , selectStatement.c_str() ,callback ,0, &errMsg);

   char **selectResult=NULL;
   int nRow,nCol;
   sqlite3_get_table(pDB, selectStatement.c_str(),&selectResult, &nRow, &nCol, 0);

   //nRow 指示出多少行
   //nCol 指示出有多少列
   //从selectResult中可以解析出所有记录，记录子字符串
  // 第n列的名称，存放在selectResult[n]
   //第n行第m列的数据，存放在selectResult[(m+1)*nCol+m]
   std::cout << "The row number of result is: " << nRow << std::endl;
   std::cout << "The column number of result is: " << nCol << std::endl;

   std::cout <<"The result ans is: ";
   for(int i=0;i<vars.size();i++){
	   std::cout << vars.at(i)+" ";
   }
   std::cout << std::endl;


	   for(int j=0;j<nRow;j++){
		   NTuple result_Ntuple;
		   for(int i=0;i<nCol;i++){
			   Binding result_Binding;
			   result_Binding.variableName=vars.at(i);
			   result_Binding.value=selectResult[(j+1)*nCol+i];
			   result_Ntuple.bindings.push_back(result_Binding);
		   }
		   partialResult.push_back(result_Ntuple);
	   }
   // 使用完后，务必释放为记录分配的内存
   	sqlite3_free_table(selectResult);

    sqlite3_close(pDB);

	return partialResult;
}

std::string ResultHandler::iToString(int i){
	std::ostringstream i_s;
	i_s <<i;
	return i_s.str();
}
